﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NETMovie.Entities;
using NETMovie.Repositories;

namespace NETMovie.BLL
{
    public class MovieService
    {
        public List<string> Errors
        {
            get;
            set;
        }

        public MovieService()
        {
            Errors = new List<string>();
        }

        public int CreateMovie(Movie movie)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                // Check inputs
                if (!movie.IsValid)
                {
                    Errors.AddRange(movie.GetRuleViolations());
                    return 0;
                }

                // Check if the movie exists in the DB.
                if (repo.GetMovie(movie.Title) != null)
                {
                    Errors.Add("The movie exists in the system");
                    return 0;
                }
                
                try
                {
                    // Create user in the DB
                    return repo.CreateMovie(movie);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }

        public bool EditMovie(Movie movie)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                try
                {
                    // Create user in the DB
                    return repo.EditMovie(movie);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }

        public bool AddMovieCastMember(IEnumerable<CastMember> CastMemberList, int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                try
                {
                
                    // Create user in the DB
                    return repo.AddMovieCastMember(CastMemberList, movieId);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }

          public bool EditMovieCastMembers(IEnumerable<CastMember> CastMemberList, int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                try
                {
                
                    // Create user in the DB
                    return repo.EditMovieCastMembers(CastMemberList, movieId);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }

          public bool DeleteMovieCastMember(int CastMemberId, int movieId)
          {
              NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

              using (IMovieRepository repo = factory.GetMovieRepository())
              {
                  try
                  {

                      // Create user in the DB
                      return repo.DeleteMovieCastMember(CastMemberId, movieId);
              
                  }
                  catch (Exception e)
                  {
                      // logger.Debug(e.Message);
                      throw e;
                  }
              }
          }


        public bool AddMovieArticle(Article article, int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                try
                {

                    // Create user in the DB
                    return repo.AddMovieArticle(article, movieId);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }


        public Article EditMovieArticle(int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                try
                {

                    // Create user in the DB
                    return repo.GetMovieArticle(movieId);
                }
                catch (Exception e)
                {
                    // logger.Debug(e.Message);
                    throw e;
                }
            }
        }
        

        public UserComment[] GetComments(int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                if (GetMovie(movieId) == null)
                {
                    Errors.Add("The movie does not exist any more");
                    return null;
                }

                UserComment[] comments = repo.GetComments(movieId);
                return comments;
            }
        }

        public Movie GetMovie(int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                return repo.GetMovie(movieId);
            }
        }

        public Movie GetMovie(string movieTitle)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                return repo.GetMovie(movieTitle);
            }
        }

        public bool DeleteMovie(int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                Movie movie = repo.GetMovie(movieId);
                movie.DeleteFlg = true;
                return repo.SaveMovie(movie);
            }
        }

        public CastMember[] GetMovieCastMembers(int movieId)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                Movie movie = repo.GetMovie(movieId);
                movie.DeleteFlg = true;
                return repo.GetMovieCastMembers(movieId);
            }

        }

        public bool AddUserComment(int movieId, UserComment comment)
        {
            bool success = false;
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                success = repo.CreateComment(movieId, comment);
            }
            
            return success;
        }

        public IEnumerable<Movie> GetMovies(string title, string category, string keywords, bool showDelete)
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {

                return repo.GetMovies(title, category, keywords,showDelete);
            }
        }

        public MovieCategory[] GetCategories()
        {
            NETMovie.Repositories.RepositoryFactory factory = RepositoryHelper.GetFactory(Repositories.RepositoryTypes.EF);

            using (IMovieRepository repo = factory.GetMovieRepository())
            {
                return repo.GetAllCategories();
            }
        }
    }
}
